package com.johnsoft.pph;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import com.johnsoft.mc.Version;

public class InstallerCreator {
	
	Scanner console;
	Version mcVersion;
	CabWriter cab;

	public static void main(String[] args) {
		try {
			new InstallerCreator();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public InstallerCreator() throws IOException {
		System.out.println("The Install Creator is designed for Windows Platforms!");
		System.out.print("Preparing Data Creation...");
		//Input
		console = new Scanner(System.in);
		
		//Data
		mcVersion = new Version();

		//Output
		cab = new CabWriter();
		
		System.out.println("Done");
		
		//Client or Server
		System.out.print("Is the setup meant for the client? (y/n) ");
		String client;
		while(!(client = console.nextLine()).equals("y")  && !client.equals("n")) {
			System.out.print("Is the setup meant for the client? (y/n) ");
		}
		
		if(client.equals("y"))
			cab.writeByte((byte)1);
		else
			cab.writeByte((byte)0);
		
		//Supported Versions
		System.out.print("Supported Minecraft Versions (Seperated by \",\" if needed): ");
		String versions = console.nextLine();
		String[] supVersions = versions.split(",");
		
		//int, string (x int value)
		cab.writeByte((byte)supVersions.length);
		for(int i = 0; i < supVersions.length; i++) {
			String hash = mcVersion.getVersion(supVersions[i]);
			System.out.println("Adding Support For: " + supVersions[i] + " ("+ hash +")");
			cab.writeString(hash);
		}
		
		new File("minecraft_jar/").mkdir();
		new File("modloader/").mkdir();
		new File("modloadermp/").mkdir();
		System.out.print("Fill the (created) minecraft_jar folder with the sources for minecraft(_server).jar, Press \"Enter\" when done");
		console.nextLine();
		System.out.print("Fill the (created) modloader folder with the modloader classes, Press \"Enter\" when done");
		console.nextLine();
		System.out.print("Fill the (created) modloadermp folder with the modloadermp classes, Press \"Enter\" when done");
		console.nextLine();
		
		System.out.println("Packing it all up!");
		packData(cab, "minecraft_jar/");
		packData(cab, "modloader/");
		packData(cab, "modloadermp/");
		
		cab.close();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {}
		System.out.println("Finished packing");
		System.out.print("Version of PPH: ");
		String filename = console.nextLine();
		if(!new File("install.pph").renameTo(new File(filename + ".pph")))
			System.out.println("Failed to rename! Setup is called: install.pph, please rename it manually");
		else
			System.out.println("Setup up Saved in: " + filename + ".pph");
	}
	
	private void packData(CabWriter cab, String folder) {
		File resources = new File(folder);
		String[] files = resources.list();
		
		//No Files? WUT!
		if(files == null) {
			return;
		}
		
		System.out.println("Packing " + resources.getAbsolutePath());
		
		for (int i = 0; i < files.length; i++) {
			File file = new File(folder + files[i]);
			processFile(cab, file, folder);
		}
	}
	
	private void processFile(CabWriter cab, File file, String folder) {
		if(file.isDirectory()) {
			packFolder(cab, file, folder + file.getName() + "\\");
		} else if (file.getAbsolutePath().toLowerCase().endsWith(".png")) {
			//Deflate and then pack
			new Pngout(file);
			byte[] bytes = readFile(file);
			cab.writeFile(bytes, folder + file.getName());
		} else {
			byte[] data = readFile(file);
			cab.writeFile(data, folder + file.getName());
		}
	}
	
	private void packFolder(CabWriter Cab, File folder, String folderPath) {
		//Pack All Resources in sub-dir
		String folderBase = folder.getAbsolutePath() + "\\";
		System.out.println("Packing " + folderBase);
		File f = new File(folderBase);
		String[] files = f.list();
		if(files == null){
			return;
		}
		for(int i = 0; i < files.length; i++) {
			File file = new File(folderBase + files[i]);
			processFile(cab, file, folderPath);
		}
	}
	
	private byte[] readFile(File f) {
		try {
			BufferedInputStream input = new BufferedInputStream(new FileInputStream(f));
			byte[] file = new byte[input.available()];
			input.read(file, 0, input.available());
			return file;
		} catch (IOException e) {
			System.err.println("RESTART THE INSTALL CREATION! A file could not be accesed during the read time!");
			e.printStackTrace();
			return new byte[] { };
		}
		
	}
	

}
